home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / diropus4.12b_gpl / dopus_print / doprint.c < prev    next >
C/C++ Source or Header  |  2000-01-27  |  16KB  |  575 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "print.h"
  32. #include "ppdata.h"
  33.  
  34. struct PrintHandle {
  35.     int filehandle;
  36.     struct MsgPort *port;
  37.     struct IOStdReq *ioreq;
  38.     char *filename;
  39.     int current_line;
  40.     int current_page;
  41.     int paper_lines;
  42.     int paper_width;
  43.     int paper_height;
  44.     char buffer[1024];
  45.     char datebuf[12];
  46.     char fileoutput;
  47.     struct RequesterBase *reqbase;
  48.     struct RastPort *req_rp;
  49.     int total_pos;
  50.     int filesize;
  51.     int progress_y;
  52.     int req_width;
  53. };
  54.  
  55. do_header_footer(struct PrintHandle *,PrintData *,int);
  56. do_printstyle(struct PrintHandle *,int,int);
  57. print_str(struct PrintHandle *,char *,int);
  58. printer_command(struct RequesterBase *,struct PrintHandle *,char *);
  59. check_print_abort(struct RequesterBase *);
  60. void show_progress(struct PrintHandle *);
  61.  
  62. char
  63.     *esc_styles[]={
  64.         "\x1b[0m",         /* STYLE_NORMAL       */
  65.         "\x1b[1m",         /* STYLE_BOLD         */
  66.         "\x1b[3m",         /* STYLE_ITALICS      */
  67.         "\x1b[4m",         /* STYLE_UNDERLINED   */
  68.         "\x1b[4\"z",       /* STYLE_DOUBLESTRIKE */
  69.         "\x1b[6\"z"};      /* STYLE_SHADOW       */
  70.  
  71. printfile(reqbase,filename,printdata,requester)
  72. struct RequesterBase *reqbase;
  73. char *filename;
  74. PrintData *printdata;
  75. struct Requester *requester;
  76. {
  77.     int fileh=0,a,lastspace=-1,margin,filesize,ret=0;
  78.     int buffersize,size,pos=0,bufpos=0;
  79.     char *buffer=NULL,*linebuffer,*marginbuf;
  80.     struct PrintHandle *handle;
  81.     struct DOpusRemember *memkey=NULL;
  82.     struct DOpusDateTime *datetime;
  83.     struct TextFont *font;
  84.  
  85.     FOREVER {
  86.         if (CheckExist(filename,&filesize)<0) break;
  87.         if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_FILE],0)))
  88.             return(0);
  89.     }
  90.  
  91.     if (!(datetime=LAllocRemember(&memkey,sizeof(struct DOpusDateTime),MEMF_CLEAR)) ||
  92.         !(handle=LAllocRemember(&memkey,sizeof(struct PrintHandle),MEMF_CLEAR))) {
  93.         LFreeRemember(&memkey);
  94.         return(0);
  95.     }
  96.  
  97.     handle->paper_lines=(printdata->bottom_margin-printdata->top_margin)+1;
  98.     handle->paper_height=handle->paper_lines;
  99.     if (printdata->headfoot[FOOTER].headfoot_flags) handle->paper_lines-=2;
  100.     handle->paper_width=(printdata->right_margin-printdata->left_margin)+1;
  101.     handle->filename=BaseName(filename);
  102.     handle->reqbase=reqbase;
  103.  
  104.     if ((margin=printdata->left_margin-1)>0) {
  105.         if (!(marginbuf=LAllocRemember(&memkey,margin+1,MEMF_CLEAR)))
  106.             goto ENDPRINT;
  107.         for (a=0;a<margin;a++) marginbuf[a]=' ';
  108.     }
  109.     if (!(linebuffer=LAllocRemember(&memkey,(handle->paper_width*2)+4,MEMF_CLEAR)))
  110.         goto ENDPRINT;
  111.  
  112.     if (Request(requester,reqbase->rb_window)) {
  113.         font=reqbase->rb_window->RPort->Font;
  114.         handle->req_rp=requester->ReqLayer->rp;
  115.         handle->req_width=requester->Width;
  116.         Do3DBox(handle->req_rp,2,1,
  117.             requester->Width-4,requester->Height-2,
  118.             reqbase->rb_shine,reqbase->rb_shadow);
  119.         SetAPen(handle->req_rp,reqbase->rb_fg);
  120.         SetBPen(handle->req_rp,reqbase->rb_bg);
  121.         SetDrMd(handle->req_rp,JAM2);
  122.         SetFont(handle->req_rp,font);
  123.         handle->progress_y=font->tf_YSize*3;
  124.         print_status(handle,
  125.             (printdata->print_flags&PRINTFLAG_FILE && printdata->output_file[0])?
  126.                 string_table[STR_CREATING_FILE]:
  127.             string_table[STR_OPENING_PRINTER],
  128.             handle->progress_y);
  129.     }
  130.  
  131.     if (printdata->print_flags&PRINTFLAG_FILE && printdata->output_file[0]) {
  132.         FOREVER {
  133.             if ((handle->filehandle=Open(printdata->output_file,
  134.                 (a=(CheckExist(printdata->output_file,NULL))?MODE_READWRITE:MODE_NEWFILE)))) {
  135.                 if (a==MODE_READWRITE) Seek(handle->filehandle,0,OFFSET_END);
  136.                 handle->fileoutput=1;
  137.                 break;
  138.             }
  139.             if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_OUTPUT],0)))
  140.                 goto ENDPRINT;
  141.         }
  142.     }
  143.     else {
  144.         struct Preferences *prefs;
  145.  
  146.         if (!(handle->port=LCreatePort(NULL,0)) ||
  147.             !(handle->ioreq=(struct IOStdReq *)LCreateExtIO(handle->port,sizeof(struct IOStdReq))))
  148.             goto ENDPRINT;
  149.  
  150.         FOREVER {
  151.             if (!(OpenDevice("printer.device",0,(struct IORequest *)handle->ioreq,0))) break;
  152.             if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_PRINTER],0))) {
  153.                 LDeleteExtIO((struct IORequest *)handle->ioreq);
  154.                 handle->ioreq=NULL;
  155.                 goto ENDPRINT;
  156.             }
  157.         }
  158.         prefs=&(((struct PrinterData *)handle->ioreq->io_Device)->pd_Preferences);
  159.  
  160.         prefs->PrintLeftMargin=1;
  161.         prefs->PrintRightMargin=printdata->right_margin;
  162.  
  163.         prefs->PaperLength=printdata->bottom_margin+2;
  164.  
  165.         if (printdata->print_pitch==PITCH_PICA) prefs->PrintPitch=PICA;
  166.         else if (printdata->print_pitch==PITCH_FINE) prefs->PrintPitch=FINE;
  167.         else if (printdata->print_pitch==PITCH_ELITE) prefs->PrintPitch=ELITE;
  168.  
  169.         if (printdata->text_quality==QUALITY_DRAFT) prefs->PrintQuality=DRAFT;
  170.         else prefs->PrintQuality=LETTER;
  171.  
  172.         if (!(printer_command(reqbase,handle,"\033#1"))) goto ENDPRINT;
  173.     }
  174.  
  175.     if (handle->req_rp) {
  176.         SetAPen(handle->req_rp,reqbase->rb_bg);
  177.         RectFill(handle->req_rp,2,1,
  178.             requester->Width-3,requester->Height-2);
  179.         print_status(handle,string_table[STR_LOADING_FILE],handle->progress_y);
  180.     }
  181.  
  182.     if (PPBase) {
  183.         FOREVER {
  184.             if ((a=ppLoadData(filename,
  185.                 DECR_POINTER,
  186.                 MEMF_CLEAR,
  187.                 (UBYTE **)&buffer,
  188.                 &buffersize,
  189.                 NULL))==PP_PASSERR) {
  190.                 if (!(check_error(reqbase,string_table[STR_INCORRECT_PASSWORD],0)))
  191.                     goto ENDPRINT;
  192.             }
  193.             else break;
  194.         }
  195.         size=buffersize;
  196.         filesize=buffersize;
  197.     }
  198.  
  199.     if (!buffer) {
  200.         buffersize=filesize;
  201.         while (!(buffer=AllocMem(buffersize,MEMF_CLEAR))) {
  202.             buffersize/=2;
  203.             if (buffersize==0) goto ENDPRINT;
  204.         }
  205.         if (!(fileh=Open(filename,MODE_OLDFILE))) goto ENDPRINT;
  206.         size=Read(fileh,buffer,buffersize);
  207.     }
  208.  
  209.     handle->filesize=filesize;
  210.  
  211.     if (handle->req_rp) {
  212.         print_status(handle,
  213.             string_table[STR_PRINTING_FILE],
  214.             font->tf_YSize);
  215.         print_status(handle,
  216.             string_table[STR_PRESS_ESCAPE],
  217.             (font->tf_YSize*5));
  218.         show_progress(handle);
  219.     }
  220.  
  221.     DateStamp(&datetime->dat_Stamp);
  222.     datetime->dat_Format=FORMAT_DOS;
  223.     datetime->dat_StrDate=handle->datebuf;
  224.     StampToStr(datetime);
  225.  
  226.     FOREVER {
  227.         if (bufpos>=size && (!fileh || (size=Read(fileh,buffer,buffersize))<1)) {
  228.             if (pos>0) {
  229.                 if ((marginbuf && !(print_str(handle,marginbuf,-1))) ||
  230.                     !(print_str(handle,linebuffer,pos))) goto ENDPRINT;
  231.             }
  232.             if (handle->current_line<=handle->paper_lines) {
  233.                 if (handle->current_line==0) {
  234.                     for (a=1;a<printdata->top_margin;a++)
  235.                         if (!(print_str(handle,"\n",1))) goto ENDPRINT;
  236.                     ++handle->current_page;
  237.                 }
  238.                 if (printdata->headfoot[FOOTER].headfoot_flags) {
  239.                     for (;handle->current_line<handle->paper_lines;handle->current_line++)
  240.                         if (!(print_str(handle,"\n",1))) goto ENDPRINT;
  241.                     if (!(do_header_footer(handle,printdata,FOOTER)))
  242.                         break;
  243.                 }
  244.             }
  245.             if (handle->current_line>0 &&
  246.                 printdata->print_flags&PRINTFLAG_EJECT &&
  247.                 !(print_str(handle,"\f",1))) break;
  248.             break;
  249.         }
  250.         bufpos=0;
  251.         while (bufpos<size) {
  252.             if (check_print_abort(reqbase)) goto ENDPRINT;
  253.             if (handle->current_line<handle->paper_lines) {
  254.                 if (handle->current_line==0) {
  255.                     for (a=1;a<printdata->top_margin;a++)
  256.                         if (!(print_str(handle,"\n",1))) goto ENDPRINT;
  257.                     ++handle->current_page;
  258.                 }
  259.                 if (handle->current_line==0 &&
  260.                     printdata->headfoot[HEADER].headfoot_flags) {
  261.                     if (!(do_header_footer(handle,printdata,HEADER))) goto ENDPRINT;
  262.                     handle->current_line+=2;
  263.                 }
  264.                 else {
  265.                     while (bufpos<size && handle->current_line<handle->paper_lines) {
  266.                         if (check_print_abort(reqbase)) goto ENDPRINT;
  267.  
  268.                         switch (buffer[bufpos]) {
  269.  
  270.                             /* Tab character; pad buffer with spaces to next tab stop */
  271.                             case '\t':
  272.                                 if ((pos%printdata->tab_size)==0) a=printdata->tab_size;
  273.                                 else a=(((pos/printdata->tab_size)+1)*printdata->tab_size)-pos;
  274.                                 while (pos<=handle->paper_width && (a--))
  275.                                     linebuffer[(pos++)]=' ';
  276.                                 lastspace=pos-1;
  277.                                 break;
  278.  
  279.                             /* Form feed */
  280.                             case '\f':
  281.                                 if (pos>0) {
  282.                                     if (marginbuf && !(print_str(handle,marginbuf,margin)))
  283.                                         goto ENDPRINT;
  284.                                     if (!(print_str(handle,linebuffer,pos))) goto ENDPRINT;
  285.                                 }
  286.                                 if (printdata->headfoot[FOOTER].headfoot_flags) {
  287.                                     for (;handle->current_line<handle->paper_lines;handle->current_line++)
  288.                                         if (!(print_str(handle,"\n",1))) goto ENDPRINT;
  289.                                 }
  290.                                 else {
  291.                                     handle->current_line=0;
  292.                                     if (!(print_str(handle,"\f",1))) goto ENDPRINT;
  293.                                 }
  294.                                 lastspace=-1; pos=0;
  295.                                 show_progress(handle);
  296.                                 break;
  297.  
  298.                             /* New line */
  299.                             case '\n':
  300.  
  301.                                 /* Only store newline character in buffer if we are not
  302.                                    on the last line of the page */
  303.  
  304.                                 if (handle->current_line<handle->paper_height-1 || handle->fileoutput)
  305.                                     linebuffer[pos++]='\n';
  306.  
  307.                                 if (marginbuf && !(print_str(handle,marginbuf,margin)))
  308.                                     goto ENDPRINT;
  309.                                 if (!(print_str(handle,linebuffer,pos))) goto ENDPRINT;
  310.                                 lastspace=-1; pos=0; ++handle->current_line;
  311.                                 show_progress(handle);
  312.                                 break;
  313.  
  314.                             default:
  315.                                 if (isspace(buffer[bufpos])) lastspace=pos;
  316.                                 else if (ispunct(buffer[bufpos])) {
  317.                                     if (lastspace==-1 || pos>lastspace+8) lastspace=pos;
  318.                                 }
  319.                                 linebuffer[pos++]=buffer[bufpos];
  320.                                 if (pos>handle->paper_width) {
  321.                                     if (marginbuf && !(print_str(handle,marginbuf,margin)))
  322.                                         goto ENDPRINT;
  323.                                     if (lastspace>0 && lastspace<pos) {
  324.                                         a=lastspace+1;
  325.                                         if (!(print_str(handle,linebuffer,a-(isspace(linebuffer[lastspace])?1:0))))
  326.                                             goto ENDPRINT;
  327.                                         pos-=a;
  328.                                         if (pos>0) CopyMem(&linebuffer[a],linebuffer,pos);
  329.                                     }
  330.                                     else {
  331.                                         if (!(print_str(handle,linebuffer,handle->paper_width)))
  332.                                             goto ENDPRINT;
  333.                                         linebuffer[0]=linebuffer[handle->paper_width];
  334.                                         pos=1;
  335.                                     }
  336.  
  337.                                     if (handle->current_line<handle->paper_height-1 || handle->fileoutput) {
  338.                                         if (!(print_str(handle,"\n",1))) goto ENDPRINT;
  339.                                     }
  340.  
  341.                                     if (pos<0) {
  342.                                         pos=0;
  343.                                         show_progress(handle);
  344.                                     }
  345.                                     lastspace=-1;
  346.                                     for (a=0;a<pos;a++) {
  347.                                         if (isspace(linebuffer[a])) lastspace=a;
  348.                                         else if (ispunct(linebuffer[a])) {
  349.                                             if (lastspace==-1 || pos>lastspace+8) lastspace=a;
  350.                                         }
  351.                                     }
  352.                                     ++handle->current_line;
  353.                                 }
  354.                                 break;
  355.                         }
  356.                         ++bufpos;
  357.                         ++handle->total_pos;
  358.                     }
  359.                 }
  360.             }
  361.             else {
  362.                 if (!(do_header_footer(handle,printdata,FOOTER))) goto ENDPRINT;
  363.                 handle->current_line=0;
  364.                 if (!(print_str(handle,"\f",1))) goto ENDPRINT;
  365.             }
  366.         }
  367.     }
  368.  
  369.     ret=1;
  370.  
  371. ENDPRINT:
  372.     if (buffer) FreeMem(buffer,buffersize);
  373.     if (fileh) Close(fileh);
  374.     if (handle->filehandle) Close(handle->filehandle);
  375.     if (handle->ioreq) {
  376.         CloseDevice((struct IORequest *)handle->ioreq);
  377.         LDeleteExtIO((struct IORequest *)handle->ioreq);
  378.     }
  379.     if (handle->port) LDeletePort(handle->port);
  380.     if (handle->req_rp) EndRequest(requester,reqbase->rb_window);
  381.     LFreeRemember(&memkey);
  382.     return(ret);
  383. }
  384.  
  385. do_header_footer(handle,printdata,type)
  386. struct PrintHandle *handle;
  387. PrintData *printdata;
  388. int type;
  389. {
  390.     int a,b;
  391.     int leftoffset;
  392.     int len;
  393.  
  394.     if (printdata->headfoot[type].headfoot_flags) {
  395.         leftoffset=printdata->left_margin-1;
  396.  
  397.         if (!(do_printstyle(handle,printdata->headfoot[type].text_style,1)))
  398.             return(0);
  399.  
  400.         for (a=0;a<sizeof(handle->buffer);a++) handle->buffer[a]=' ';
  401.  
  402.         if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_DATE)
  403.             CopyMem(handle->datebuf,&handle->buffer[leftoffset+1],9);
  404.  
  405.         if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_TITLE) {
  406.             char titlebuf[40];
  407.  
  408.             if (printdata->headfoot[type].headfoot_title[0])
  409.                 strcpy(titlebuf,printdata->headfoot[type].headfoot_title);
  410.             else strcpy(titlebuf,handle->filename);
  411.  
  412.             if ((a=strlen(titlebuf))>handle->paper_width) {
  413.                 a=handle->paper_width;
  414.                 b=0;
  415.             }
  416.             else b=(handle->paper_width-a)/2;
  417.             b+=leftoffset;
  418.             CopyMem(titlebuf,&handle->buffer[b],a);
  419.         }
  420.  
  421.         if (printdata->headfoot[type].headfoot_flags&HEADFOOTFLAG_PAGE) {
  422.             char pagebuf[20];
  423.  
  424.             lsprintf(pagebuf,"%s %ld",string_table[STR_PAGE],handle->current_page);
  425.  
  426.             a=leftoffset+(handle->paper_width-strlen(pagebuf)-1);
  427.             CopyMem(pagebuf,&handle->buffer[a],strlen(pagebuf));
  428.         }
  429.  
  430.         if (type==FOOTER && !(print_str(handle,"\n",-1))) return(0);
  431.  
  432.         len=leftoffset+handle->paper_width;
  433.  
  434.         if (type==HEADER || handle->fileoutput) {
  435.             handle->buffer[leftoffset+handle->paper_width]='\n';
  436.             len+=1;
  437.         }
  438.  
  439.         if (!(print_str(handle,handle->buffer,len))) return(0);
  440.  
  441.         if (type==HEADER && !(print_str(handle,"\n",-1))) return(0);
  442.  
  443.         if (!(do_printstyle(handle,printdata->headfoot[type].text_style,0)))
  444.             return(0);
  445.     }
  446.     return(1);
  447. }
  448.  
  449. do_printstyle(handle,style,turnon)
  450. struct PrintHandle *handle;
  451. int style,turnon;
  452. {
  453.     int a=1;
  454.  
  455.     if (handle->ioreq) {
  456.         if (turnon) a=print_str(handle,esc_styles[style],-1);
  457.         else {
  458.             if ((a=print_str(handle,esc_styles[0],-1))) {
  459.                 if (style==STYLE_DOUBLESTRIKE)
  460.                     a=print_str(handle,DOUBLESTRIKE_OFF,-1);
  461.                 else if (style==STYLE_SHADOW)
  462.                     a=print_str(handle,SHADOW_OFF,-1);
  463.             }
  464.         }
  465.     }
  466.     return(a);
  467. }
  468.  
  469. print_str(handle,string,stlen)
  470. struct PrintHandle *handle;
  471. char *string;
  472. int stlen;
  473. {
  474.     int len,success,seek;
  475.  
  476.     if ((len=stlen)==-1) {
  477.         if ((len=strlen(string))>handle->paper_width)
  478.             len=handle->paper_width;
  479.     }
  480.  
  481.     if (len<1) return(1);
  482.  
  483.     FOREVER {
  484.         seek=0;
  485.         if (handle->filehandle) {
  486.             success=((seek=Write(handle->filehandle,string,len))==len);
  487.         }
  488.         else if (handle->ioreq) {
  489.             handle->ioreq->io_Length=len;
  490.             handle->ioreq->io_Data=(APTR)string;
  491.             handle->ioreq->io_Command=CMD_WRITE;
  492.             success=(!(DoIO((struct IORequest *)handle->ioreq)));
  493.         }
  494.         else return(0);
  495.         if (success) return(1);
  496.         if (!(check_error(handle->reqbase,string_table[STR_PRINT_ERROR],0))) return(0);
  497.         if (seek>0) Seek(handle->filehandle,-seek,0);
  498.     }
  499. }
  500.  
  501. printer_command(reqbase,handle,command)
  502. struct RequesterBase *reqbase;
  503. struct PrintHandle *handle;
  504. char *command;
  505. {
  506.     handle->ioreq->io_Length=-1;
  507.     handle->ioreq->io_Data=(APTR)command;
  508.     handle->ioreq->io_Command=CMD_WRITE;
  509.  
  510.     FOREVER {
  511.         if (!(DoIO((struct IORequest *)handle->ioreq))) break;
  512.         if (!(check_error(reqbase,string_table[STR_UNABLE_TO_OPEN_PRINTER],0)))
  513.             return(0);
  514.     }
  515.     return(1);
  516. }
  517.  
  518. check_print_abort(reqbase)
  519. struct RequesterBase *reqbase;
  520. {
  521.     struct IntuiMessage *msg;
  522.     int abort=0;
  523.  
  524.     while (msg=(struct IntuiMessage *)GetMsg(reqbase->rb_window->UserPort)) {
  525.         if (msg->Class==IDCMP_VANILLAKEY && msg->Code==0x1b) {
  526.             if (check_error(reqbase,string_table[STR_REALLY_ABORT],1))
  527.                 abort=1;
  528.         }
  529.         ReplyMsg((struct Message *)msg);
  530.     }
  531.     return(abort);
  532. }
  533.  
  534. void show_progress(handle)
  535. struct PrintHandle *handle;
  536. {
  537.     float percent;
  538.     char buf[20];
  539.  
  540.     if (!handle->total_pos || !handle->filesize) percent=0;
  541.     else percent=((float)((float)handle->total_pos/(float)handle->filesize))*100;
  542.  
  543.     lsprintf(buf,"%3ld%% %s ",(int)percent,string_table[STR_COMPLETE]);
  544.     print_status(handle,buf,handle->progress_y);
  545. }
  546.  
  547. void print_status(handle,text,y)
  548. struct PrintHandle *handle;
  549. char *text;
  550. int y;
  551. {
  552.     int x;
  553.     struct TextFont *font;
  554.     struct RequesterBase *reqbase;
  555.  
  556.     reqbase=handle->reqbase;
  557.     font=handle->req_rp->Font;
  558.     x=(handle->req_width-((strlen(text))*font->tf_XSize))/2;
  559.     if (x>1) {
  560.         SetAPen(handle->req_rp,reqbase->rb_bg);
  561.         RectFill(handle->req_rp,
  562.             2,y,
  563.             x,y+font->tf_YSize);
  564.     }
  565.     SetAPen(handle->req_rp,reqbase->rb_fg);
  566.     UScoreText(handle->req_rp,text,x,y+font->tf_Baseline,-1);
  567.     if (handle->req_rp->cp_x<handle->req_width-2) {
  568.         SetAPen(handle->req_rp,reqbase->rb_bg);
  569.         RectFill(handle->req_rp,
  570.             handle->req_rp->cp_x,y,
  571.             handle->req_width-3,y+font->tf_YSize);
  572.     }
  573.     SetAPen(handle->req_rp,reqbase->rb_fg);
  574. }
  575.